﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using WindowsAPI.Windows;

namespace WindowsAPI
{
    public partial class ComputerComponent : Component
    {
        /* ------------------------------------------------------------------------------------------ */



        /* ------------------------------------------------------------------------------------------ */



        /* ------------------------------------------------------------------------------------------ */

        [Category("Computer")]
        public KeyboardComponent Keyboard { get { return f_Keyboard; } }
        [Category("Computer")]
        public MouseComponent Mouse { get { return f_Mouse; } }
        [Category("Computer")]
        public FileSystemComponent FileSystem { get { return f_FileSystem; } }
        [Category("Computer")]
        public RegistryComponent Registry { get { return f_Registry; } }

        public DateTime LocalTime
        {
            get { return DateTime.Now; }
            set
            {
                var time = (SYSTEMTIME)value;
                Kernel32.SetLocalTime(ref time);
            }
        }

        public string DesktopWallpaper
        {
            get
            {
                var filename = new StringBuilder(Consts.MAX_PATH);
                if(!User32.SystemParametersInfo(SPI.GETDESKWALLPAPER, Consts.MAX_PATH, filename, SPIF.None))
                    Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
                return filename.ToString();
            }
            set
            {
                var filename = new StringBuilder(value ?? string.Empty);
                if(!User32.SystemParametersInfo(SPI.SETDESKWALLPAPER, 0, filename, SPIF.SPIF_SENDCHANGE))
                    Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());

            }
        }

        public string Name
        {
            get
            {
                var buffer = new StringBuilder(255);
                if(!Kernel32.GetComputerName(buffer, buffer.Capacity))
                    Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
                return buffer.ToString();
            }
            set { if(!Kernel32.SetComputerName(value)) Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error()); }
        }

        /* ------------------------------------------------------------------------------------------ */

        public ComputerComponent() { InitializeComponent(); }

        public ComputerComponent(IContainer container) { container.Add(this); InitializeComponent(); }

        /* ------------------------------------------------------------------------------------------ */

        public bool LockWorkStation() { return User32.LockWorkStation(); }

        //public bool Shutdown(ExitWindowsFlags flags = ExitWindowsFlags.ShutDown, 
        //    ShutdownReason reason = ShutdownReason.MajorOther)
        //{
        //    return User32.ExitWindowsEx(flags, reason);
        //}

        public static bool Shutdown(int Timeout = 0, bool Force = false, bool ReBoot = false,
            ShutdownReason Reason = ShutdownReason.MajorOther)
        {
            IntPtr htok;

            if(AdvAPI32.OpenProcessToken(Process.GetCurrentProcess().Handle,
                DesiredAccessType.TOKEN_ADJUST_PRIVILEGES | DesiredAccessType.TOKEN_QUERY, out htok))
            {
                //заполняем поля структуры
                var tkp = new TOKEN_PRIVILEGES { PrivilegeCount = 1, Attributes = AdvAPI32.SE_PRIVILEGE_ENABLED, Luid = 0 };
                //получаем системный идентификатор необходимой нам привилегии
                AdvAPI32.LookupPrivilegeValue(null, SE_Signatures.SE_SHUTDOWN_NAME, out tkp.Luid);
                //повышем привилигеию своему процессу
                AdvAPI32.AdjustTokenPrivileges(htok, false, ref tkp, 0, IntPtr.Zero, IntPtr.Zero);
                return AdvAPI32.InitiateSystemShutdownEx(null, null, Timeout, Force, ReBoot, Reason);
            }
            return false;
        }

        public void OpenCD(bool Open = true)
        {
            WinMM.mciSendString(string.Format("set CDAudio door {0} wait", (Open ? "open" : "closed")),
                new StringBuilder(), 127, IntPtr.Zero);
        }

        public void StartScreenSaver()
        {
            const int SC_SCREENSAVE = 0xF140;
            Window.Desktop.SendMessage(WM.SYSCOMMAND, (IntPtr)SC_SCREENSAVE);
        }

        /* ------------------------------------------------------------------------------------------ */
    }
}
